package org.cagui.core;

import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JRadioButton;

import org.apache.commons.codec.binary.Base64;


public class KeyStoreManager {
	public static final String defaultKeyStorePath = "./keystores/keystore.ks";
	public static final String path = "./keystores/";

	private String actPath;
	private String actPass;
	
	private KeyStore actKeyStore;
	
	public Key getPrivateKeyFromKeyStore(String pathToKeyStore, String keyStorePassword, String keyAlias, String keyPassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException{
		
		KeyStore privateKeyStore = loadKeyStore(pathToKeyStore, keyStorePassword);
		
		Key privateKey = privateKeyStore.getKey(keyAlias, keyPassword.toCharArray());
		
		return privateKey;
	}
	
	public KeyStore loadKeyStore(String pathToKeyStore, String keyStorePassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
		
		KeyStore privateKeyStore = KeyStore.getInstance("JKS");  	    
	    FileInputStream fis = new FileInputStream(pathToKeyStore);  	    
	    privateKeyStore.load(fis, keyStorePassword.toCharArray());
	    fis.close();
	    
	    return privateKeyStore;		
	}
	
	public void generateNewKeyStore(String keyStoreFileName, String keyStorePassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
	{
		KeyStore ks = KeyStore.getInstance("JKS");
		ks.load( null, null );
		ks.store( new FileOutputStream( path + keyStoreFileName + ".ks" ), keyStorePassword.toCharArray() );  
	}
	
	/**
	 * 
	 * If the protected key is of type java.security.PrivateKey, it must be accompanied by a certificate 
	 * chain certifying the corresponding public key. If the underlying keystore implementation is of type 
	 * jks, key must be encoded as an EncryptedPrivateKeyInfo as defined in the PKCS #8 standard.
	 *
	 * If the given alias already exists, the keystore information associated with it is overridden by the 
	 * given key (and possibly certificate chain). 
	 * 
	 */
	public void saveKeyInKeyStore(KeyStore keyStore, Key key, String keyAlias, String keyPassword, Certificate[] chain) throws KeyStoreException
	{
		keyStore.setKeyEntry(keyAlias, key,  
				keyPassword.toCharArray(),  
				chain);  
	}
	
	public List<String> getActualKeyStoreContent() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
		return getKeyStoreContent(actPath, actPass);
	}
	
	public List<String> getKeyStoreContent(String pathToKeyStore, String keyStorePassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
		
		List<String> aliases = new ArrayList<String>();
		
		KeyStore privateKeyStore = loadKeyStore(pathToKeyStore, keyStorePassword);
	    
	    Enumeration<String> keyAliases = privateKeyStore.aliases();
	    for (; keyAliases.hasMoreElements(); ) {
	        String alias = (String)keyAliases.nextElement();
	        aliases.add(alias);

	        // Does alias refer to a private key?
	        //if (privateKeyStore.isKeyEntry(alias)) System.out.println("Key: " + alias);

	        //if (privateKeyStore.isCertificateEntry(alias)) System.out.println("Certificate: " + alias);

	        // Does alias refer to a trusted certificate?
	        //b = privateKeyStore.isCertificateEntry(alias);
	    }
	    
		return aliases;
	}
	
	public boolean isPasswordValid(String pathToKeyStore, String keyStorePassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
		try {
			loadKeyStore(pathToKeyStore, keyStorePassword);
		} catch (Exception e) {
			
			setActPath(null);
			setActPass(null);
			setActKeyStore(null);
			return false;
		}
		
		setActPath(pathToKeyStore);
		setActPass(keyStorePassword);
		setActKeyStore(loadKeyStore(pathToKeyStore,keyStorePassword));
		
		return true;
	}
	
	public boolean isPasswordValidForKey(String alias, String keyPassword){
		try {
			
			actKeyStore.getKey(alias, keyPassword.toCharArray());
			
		} catch (Exception e) {
			
			return false;
			
		}

		return true;
	}
	
	public String getKeyContent(String alias, String keyPassword) throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException{
	       
        Key key = actKeyStore.getKey(alias, keyPassword.toCharArray());
        
        String b64 = new String(Base64.encodeBase64(key.getEncoded(), true));
        
        return "-----BEGIN PRIVATE KEY-----\n" + b64 + "-----END PRIVATE KEY-----";
	}
	
	public String[] getKeystoresNames(){
		File dir = new File("./keystores/");

		String[] children = dir.list();
			
		return children;
	}
	
	public void removeKeyFromKeyStore(String keyName, KeyStore keyStore) throws KeyStoreException{
		keyStore.deleteEntry(keyName);
	}

	public String getActPath() {
		return actPath;
	}

	public void setActPath(String actPath) {
		this.actPath = actPath;
	}

	public String getActPass() {
		return actPass;
	}

	public void setActPass(String actPass) {
		this.actPass = actPass;
	}

	public KeyStore getActKeyStore() {
		return actKeyStore;
	}

	public void setActKeyStore(KeyStore actKeyStore) {
		this.actKeyStore = actKeyStore;
	}
	
	
	
}
